package org.liaohailong.victorlibrary.widget

import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
import androidx.annotation.Keep


/**
 * create by liaohailong
 * time 2022/12/2 9:10
 * desc: 光圈View
 * 郭霖每日推文，作者：史大拿
 * 学习：
 * -> LinearGradient 参数配置
 * -> outlineProvider + clipToOutline 实现圆角裁剪
 * -> by lazy 使用
 * -> ObjectAnimator + kotlin的set函数 + invalidate 组合
 * -> 动画实现思路：三层图层，方块旋转，遮蔽中心，形成边线移动动画。
 * -> 动画搭配 onAttachedToWindow + onDetachedFromWindow，避免过度开销
 *
 */
class ApertureView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
    View(context, attrs, defStyleAttr) {
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context) : this(context, null)

    private val radius = 20 * 3.0F
    private val strokeWidth = 10 * 3.0F


    private val rectF = RectF()
    private val leftTopRectF = RectF()
    private val rightBottomRectF = RectF()
    private val leftTopShader by lazy {
        LinearGradient(
            leftTopRectF.right,
            leftTopRectF.top,
            leftTopRectF.left,
            leftTopRectF.bottom,
            intArrayOf(Color.RED, Color.TRANSPARENT),
            floatArrayOf(0.0f, 1.0f),
            Shader.TileMode.CLAMP
        )
    }
    private val rightBottomShader by lazy {
        LinearGradient(
            rightBottomRectF.left,
            rightBottomRectF.bottom,
            rightBottomRectF.right,
            rightBottomRectF.top,
            intArrayOf(Color.BLUE, Color.TRANSPARENT),
            floatArrayOf(0.0f, 1.0f),
            Shader.TileMode.CLAMP
        )
    }

    private val paint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL_AND_STROKE
    }

    private val animator by lazy {
        ObjectAnimator.ofFloat(this, "angle", 0.0f, 360.0f).apply {
            repeatCount = ObjectAnimator.INFINITE
            interpolator = null
            duration = 2000L
        }
    }

    init {
        // 圆角裁剪
        outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View, outline: Outline) {
                outline.setRoundRect(0, 0, view.width, view.height, radius)
            }
        }
        clipToOutline = true
    }

    @Keep
    var angle = 0.0f
        set(value) {
            field = value
            invalidate()
        }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        animator.start()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        animator.cancel()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        rectF.set(0f, 0f, w.toFloat(), h.toFloat())

        // 左上角矩形区域
        leftTopRectF.set(
            rectF.left - rectF.width() / 2f,
            rectF.top - rectF.height() / 2f,
            rectF.left + rectF.width() / 2f,
            rectF.top + rectF.height() / 2f
        )
        // 右下角矩形区域
        rightBottomRectF.set(
            leftTopRectF.right,
            leftTopRectF.bottom,
            leftTopRectF.right + rectF.width(),
            leftTopRectF.bottom + rectF.height()
        )
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        val save = canvas.save()

        // 旋转
        canvas.rotate(angle, rectF.centerX(), rectF.centerY())

        // 绘制左上的矩形
        paint.shader = leftTopShader
        canvas.drawRect(leftTopRectF, paint)
        paint.shader = null

        // 绘制右上的矩形
        paint.shader = rightBottomShader
        canvas.drawRect(rightBottomRectF, paint)
        paint.shader = null

        canvas.restoreToCount(save)

        // 遮挡
        paint.color = Color.parseColor("#E8E8E8")
        canvas.drawRoundRect(
            rectF.left + strokeWidth,
            rectF.top + strokeWidth,
            rectF.right - strokeWidth,
            rectF.bottom - strokeWidth,
            radius, radius,
            paint
        )


    }
}